// i.r(t), i.d(t, { default: () => ShowcaseAnalytics })
import Module from "./Module"
import ApiClientModule from "./ApiClientModule"
import AnalyticsModule from "./AnalyticsModule"
import AnalyticsConfig from "../utils/AnalyticsConfig"
import l from "ua-parser-js"
import paramsUtil from "../utils/params.util"
import browserUtil from "../utils/browser.util"
import p from "../math/82702"
const m = e => `${e}_3.0`,
  g = () => {
    try {
      return Intl.DateTimeFormat().resolvedOptions().timeZone
    } catch (e) {
      return ""
    }
  },
  f = () => {
    const e = new l.UAParser().getResult()
    let t = e.os.name,
      i = e.browser.name
    const n = Object.assign({}, e.device)
    return (
      browserUtil.isiPad() && ((t = "iPadOS"), (n.vendor = "Apple"), (n.model = "iPad"), (n.type = "tablet"), "Safari" === i && (i = "Mobile Safari")),
      {
        browser: {
          name: i,
          major: e.browser.major,
          version: e.browser.version,
          language: navigator.language || "",
          languages: navigator.languages ? navigator.languages.join(", ") : ""
        },
        os: { name: t, version: e.os.version },
        device: { vendor: n.vendor, model: n.model, type: n.type }
      }
    )
  }
function v(e, t) {
  return {
    app: { name: m(t), version: "3.1" },
    locale: e,
    screen: {
      width: window.screen.width,
      height: window.screen.height,
      density: window.devicePixelRatio
    },
    timezone: g(),
    location: {}
  }
}
const y = analyticsEnum.Logging
import { InteractionModeChangeMessage } from "../message/inter.message"
import InteractionmodeData from "../data/InteractionmodeData"
class InteractionmodeAnalytics {
  handlers: any
  constructor() {
    this.handlers = [
      {
        msgType: InteractionModeChangeMessage,
        func: (e, t, i) => {
          const n = i.tryGetData(InteractionmodeData)
          n &&
            e.track("interaction_mode_changed", {
              interaction_mode_prev: t.fromMode,
              interaction_mode: t.mode,
              interaction_source: n.source
            })
        }
      }
    ]
  }
}

import TourData from "../data/TourData"
function x(e, t) {
  switch (e) {
    case sweepAlignmentEnum.ALIGNED:
      return 1
    case sweepAlignmentEnum.UNALIGNED:
      return 2
  }
  switch (t) {
    case sweepPlacementEnum.MANUAL:
      return 3
  }
  return 0
}
var E = {
  USER: "self-guided",
  TOUR: "tour"
}

class CameraDataAnalytics {
  startLoadTime: number
  endLoadTime: number
  panosViewed: number
  handlers: (
    | { msgType: typeof BeginMoveToSweepMessage; func: (e: any, t: any, i: any) => void }
    | { msgType: typeof EndMoveToSweepMessage; func: (e: any, t: any, i: any) => void }
  )[]
  constructor() {
    ;(this.startLoadTime = Date.now()),
      (this.endLoadTime = Date.now()),
      (this.panosViewed = 0),
      (this.handlers = [
        {
          msgType: BeginMoveToSweepMessage,
          func: (e, t, i) => {
            this.onMoveToSweepBegin(t.timestamp)
          }
        },
        {
          msgType: EndMoveToSweepMessage,
          func: (e, t, i) => {
            const n = i.tryGetData(InteractionmodeData),
              s = i.tryGetData(TourData)
            this.endLoadTime = Date.now()
            const r = this.endLoadTime - this.startLoadTime
            e.track("pano_viewed", {
              pano_id: t.toSweep,
              pano_view_count: ++this.panosViewed,
              alignment_type: x(t.alignmentType, t.placementType),
              navigation_source: s && s.tourPlaying ? E.TOUR : E.USER,
              interaction_source: n ? n.source : InteractionmodeData.defaultSource,
              interaction_mode: n ? n.mode : InteractionmodeData.defaultMode,
              load_time: r / 1e3
            })
          }
        }
      ])
  }
  onMoveToSweepBegin(e) {
    this.startLoadTime = e
  }
}

import { EndSwitchViewmodeMessage } from "../message/viewmode.message"
class ViewmodeAnalytics {
  handlers: any
  constructor() {
    this.handlers = [
      {
        msgType: EndSwitchViewmodeMessage,
        func: (e, t, i) => {
          const n = i.tryGetData(InteractionmodeData),
            s: any = { view_mode: t.toMode }
          n && ((s.interaction_source = n.source), (s.interaction_mode = n.mode)), e.track("mode_changed", s)
        }
      }
    ]
  }
}
import MattertagDataAnalytics from "../utils/MattertagDataAnalytics"
import FloorsData from "../data/FloorsData"
const I = (e, t) => {
  const i = t.tryGetData(FloorsData)
  if (!e || !i) return -1
  return i.getFloor(e).index
}
class FloorChangeAnalytics {
  handlers: (
    | { msgType: typeof EndMoveToFloorMessage; func: (e: any, t: any, i: any) => void }
    | { msgType: typeof SweepFloorOverrideMessage; func: (e: any, t: any, i: any) => void }
  )[]
  constructor() {
    this.handlers = [
      {
        msgType: EndMoveToFloorMessage,
        func: (e, t, i) => {
          const n = i.tryGetData(InteractionmodeData)
          e.track("floor_changed", {
            floor_id: t.floorName,
            interaction_source: n ? n.source : InteractionmodeData.defaultSource,
            interaction_mode: n ? n.mode : InteractionmodeData.defaultMode
          })
        }
      },
      {
        msgType: SweepFloorOverrideMessage,
        func: (e, t, i) => {
          const n = i.tryGetData(InteractionmodeData)
          e.track("sweep_floor_fixup", {
            sweep_index: t.sweep.index,
            sweep_alignment: t.sweep.alignmentType,
            sweep_placement: t.sweep.placementType,
            sweep_floor_from: I(t.from, i),
            sweep_floor_to: I(t.to, i),
            interaction_source: n ? n.source : InteractionmodeData.defaultSource,
            interaction_mode: n ? n.mode : InteractionmodeData.defaultMode
          })
        }
      }
    ]
  }
}
import { ZoomMessage } from "../message/zoom.message"
import SweepData from "../data/SweepData"
class ZoomAnalytics {
  firstZoom: boolean
  fromZoom: number
  toZoom: number
  handlers: { msgType: typeof ZoomMessage; func: (e: any, t: any, i: any) => void }[]
  analytics: any
  currentPano: any
  sendTimeout: number
  constructor() {
    ;(this.firstZoom = !0),
      (this.fromZoom = 1),
      (this.toZoom = 1),
      (this.handlers = [
        {
          msgType: ZoomMessage,
          func: (e, t, i) => {
            this.analytics || (this.analytics = e)
            const n = i.tryGetData(SweepData)
            n && n.currentSweep !== this.currentPano && ((this.firstZoom = !0), (this.currentPano = n.currentSweep), (this.fromZoom = 1)),
              (this.toZoom = t.zoomLevel),
              clearTimeout(this.sendTimeout),
              (this.sendTimeout = window.setTimeout(this.trackZoomEvent.bind(this), 150))
          }
        }
      ])
  }

  trackZoomEvent() {
    const e = this.firstZoom ? "initial" : "followup"
    this.analytics.track("zoom_" + e, {
      from: this.fromZoom,
      to: this.toZoom,
      pano: this.currentPano
    }),
      (this.firstZoom = !1),
      (this.fromZoom = this.toZoom)
  }
}
import SymbolList from "../SymbolList"
import { AppPhaseChangeMessage } from "../message/app.message"
import ApplicationData from "../data/ApplicationData"
import Data from "../object/Data"
class TimingData extends Data {
  modelLoadingStartTime: number
  waitingStartTime: number
  appPlayingTime: number
  appStartedTime: number
  constructor() {
    super(...arguments),
      (this.name = "timing"),
      (this.modelLoadingStartTime = 0),
      (this.waitingStartTime = 0),
      (this.appPlayingTime = 0),
      (this.appStartedTime = 0)
  }
  get totalTimeToAppStarting() {
    let e = this.appStartedTime - performance.timing.navigationStart
    return this.modelLoadingStartTime && this.waitingStartTime && (e -= this.modelLoadingStartTime - this.waitingStartTime), e
  }
  get totalTimeToAppPlaying() {
    let e = this.appPlayingTime - performance.timing.navigationStart
    return this.modelLoadingStartTime && this.waitingStartTime && (e -= this.modelLoadingStartTime - this.waitingStartTime), e
  }
}
import Logger from "../utils/Logger"
import PlayerOptionsData from "../data/PlayerOptionsData"
import EngineContext from "../EngineContext"
const H = new Logger("showcase-session")
const G = new TimingData()
class ShowcaseSessionAnalytics {
  analytics: AnalyticsModule
  engine: EngineContext
  handlers: { msgType: typeof AppPhaseChangeMessage; func: (e: any, t: any, i: any) => Promise<void> }[]
  constructor(analytics: AnalyticsModule, engine: EngineContext) {
    this.analytics = analytics
    this.engine = engine
    this.handlers = [
      {
        msgType: AppPhaseChangeMessage,
        func: async (e, t, i) => {
          switch (t.phase) {
            case phaseMin.WAITING:
              G.waitingStartTime = Date.now()
              G.commit()
              e.track("impression", {
                url_params: browserUtil.queryList(),
                visible: !0
              })
              break
            case phaseMin.LOADING:
              G.modelLoadingStartTime = Date.now()
              G.commit()
              break
            case phaseMin.STARTING: {
              G.appStartedTime = Date.now()
              G.commit()
              H.info("First render, model loaded " + G.totalTimeToAppStarting / 1000)
              const t = this.engine.market.tryGetData(PlayerOptionsData)
              const i = (await this.engine.getModuleBySymbol<WebGLRendererModule>(SymbolList.WEBGL_RENDERER)).getCapabilities()
              const n = {
                has_hlr: !t || t.options.highlight_reel,
                duration: Date.now() - G.modelLoadingStartTime,
                duration_from_navigation_start: Date.now() - performance.timing.navigationStart,
                gl_v2: i.gl_v2,
                gl_max_textures: i.gl_max_textures,
                gl_max_texture_size: i.gl_max_texture_size,
                gl_max_cubemap_size: i.gl_max_cubemap_size,
                gl_instancing: i.gl_instancing,
                gl_oes_texture_float: i.gl_oes_texture_float,
                gl_oes_texture_half_float: i.gl_oes_texture_half_float,
                gl_depth_texture: i.gl_depth_texture,
                gl_draw_buffers: i.gl_draw_buffers,
                gl_oes_fbo_render_mip_map: i.gl_oes_fbo_render_mip_map,
                gl_shader_texture_lod: i.gl_shader_texture_lod,
                gl_oes_vertex_array_obj: i.gl_oes_vertex_array_obj,
                gl_ovr_multi_view: i.gl_ovr_multi_view,
                gl_color_buffer_float: i.gl_color_buffer_float,
                gl_astc_supported: i.gl_astc_supported,
                gl_etc1_supported: i.gl_etc1_supported,
                gl_etc2_supported: i.gl_etc2_supported,
                gl_dxt_supported: i.gl_dxt_supported,
                gl_bptc_supported: i.gl_bptc_supported,
                gl_pvrtc_supported: i.gl_pvrtc_supported
              }
              e.track("model_loaded", n)
              break
            }
            case phaseMin.PLAYING:
              G.appPlayingTime = Date.now()
              G.commit()
              H.info("Playing, session started " + G.totalTimeToAppPlaying / 1e3)
              e.track("session_started")
              window.addEventListener("unload", this.sessionEnded)
              e.track("load_times", {
                time_to_app_start: G.totalTimeToAppStarting,
                time_to_app_playing: G.totalTimeToAppPlaying
              })
              break
            case phaseMin.ERROR:
              const t = await i.waitForData(ApplicationData)
              const { error: n } = t
              const s = n && n.name ? n.name : n && n.constructor ? n.constructor.name : null
              const r = n ? n.message : null
              const o = n && n.stack ? n.stack.split("\n") : []
              const a = o.length >= 2 ? o[1].match(/\s+at\s+([^\s]+)/) : null
              const l = !!funcUtil.getUrlParams("oops", "")
              const c = {
                error_dialog: "oops",
                error_type: s || "",
                exception: {
                  message: `${s}: ${r}`,
                  function: a ? a[1] : null,
                  stack: o.slice(1, 5).join("\n")
                },
                duration: Date.now() - G.modelLoadingStartTime,
                duration_from_navigation_start: Date.now() - performance.timing.navigationStart,
                mock_error: l
              }
              e.track("error_displayed", c)
              break
          }
        }
      }
    ]
    this.sessionEnded = this.sessionEnded.bind(this)
  }
  sessionEnded() {
    this.analytics.trackAsync("session_ended", {
      duration: Date.now() - G.appPlayingTime
    })
  }
  dispose() {
    window.removeEventListener("unload", this.sessionEnded)
  }
}
import { BeginSwitchViewmodeMessage } from "../message/viewmode.message"
import funcUtil from "../utils/func.util"
import CircularBuffer from "../three/CircularBuffer"
import ViewmodeData from "../data/ViewmodeData"
const Y = new Logger("/index")
let $ = 0,
  Q = 1 / 0,
  X = null,
  J = null,
  ee = window.devicePixelRatio || 1
const te = {},
  ie = new CircularBuffer(1000)
class RenderingPerformanceAnalytics {
  handlers: (
    | { msgType: typeof BeginSwitchViewmodeMessage; func: (e: any, t: any, i: any) => void }
    | { msgType: typeof AppPhaseChangeMessage; func: (e: any, t: any, i: any) => void }
    | { msgType: typeof PixelRatioChangedMessage; func: (e: any, t: any, i: any) => void }
  )[]
  constructor() {
    this.handlers = [
      {
        msgType: BeginSwitchViewmodeMessage,
        func: (e, t, i) => {
          ;(J !== phaseMin.STARTING && J !== phaseMin.PLAYING) || ne(e, viewmodeEnum[t.toMode], 10000)
        }
      },
      {
        msgType: AppPhaseChangeMessage,
        func: (e, t, i) => {
          const n = i.tryGetData(ViewmodeData)
          t.phase === phaseMin.LOADING
            ? ne(e, "Loading", 6e4)
            : t.phase === phaseMin.STARTING
            ? ne(e, "Starting", 6e4)
            : t.phase === phaseMin.PLAYING && n && n.currentMode && ne(e, viewmodeEnum[n.currentMode], 1e4),
            (J = t.phase)
        }
      },
      {
        msgType: PixelRatioChangedMessage,
        func: (e, t, i) => {
          ee = t.pixelRatio
        }
      }
    ]
  }
}
function ne(e, t, i) {
  t !== X && (X && (re(e), se()), te[t] || ((X = t), (Q = i), (te[X] = !0)))
}
const se = () => {
    ;(X = null), ie.clear(), ($ = 0)
  },
  re = e => {
    const t = ie.getList()
    if (0 !== t.length)
      try {
        const i = oe(t)
        e.track("performance", i)
      } catch (e) {
        Y.warn("Could not send performance metrics", e)
      }
  },
  oe = e => {
    let t = 0,
      i = 0,
      n = 0,
      s = 0,
      r = 0,
      o = 0
    for (const a of e) (t += a), a < 0 || (a <= 16.7 ? (i += a) : a <= 33.3 ? (n += a) : a <= 100 ? (s += a) : a <= 1e3 ? (r += a) : (o += a))
    if (t <= 0) throw Error("No positive timings, cannot calculate performance data")
    const a = t / e.length
    ;(i /= t), (n /= t), (s /= t), (r /= t), (o /= t)
    const l = e.slice(),
      c = funcUtil.getArrayVal(l, 50),
      h = funcUtil.getArrayVal(l, 95, !1),
      d = l[l.length - 1]
    return {
      phase: X,
      frame_delta: a,
      frame_delta_avg: a,
      frame_delta_median: c,
      frame_delta_95th: h,
      frame_delta_max: d,
      duration: t,
      time_60_fps: i,
      time_60_30_fps: n,
      time_30_10_fps: s,
      time_10_1_fps: r,
      time_1_0_fps: o,
      pixel_ratio: ee
    }
  }
import SettingsData from "../data/SettingsData"
import {
  MeasurementCreationCancelledMessage,
  MeasurementSegmentCreatedMessage,
  MeasurementCreatedMessage,
  MeasurementTitleAddedMessage,
  MeasurementTitleChangedMessage,
  MeasurementDeletedMessage,
  MeasurementUpdatedMessage,
  MeasurementModeToggledMessage
} from "../message/measurement.message"
import FloorsViewData from "../data/FloorsViewData"
const he = (e, t) => {
  const i = t.tryGetData(FloorsViewData)
  if (!i) return -1
  return (e ? i.floors.getFloor(e) : i.getHighestVisibleFloor()).index
}
class MeasurementAnalytics {
  handlers: (
    | { msgType: typeof MeasurementSegmentCreatedMessage; func: (e: any, t: any, i: any) => void }
    | { msgType: typeof MeasurementTitleAddedMessage; func: (e: any, t: any) => void }
    | { msgType: typeof MeasurementTitleChangedMessage; func: (e: any, t: any) => void }
    | { msgType: typeof MeasurementModeToggledMessage; func: (e: any, t: any) => void }
    | { msgType: typeof MeasurementCreationCancelledMessage; func: (e: any, t: any) => void }
  )[]
  constructor() {
    this.handlers = [
      {
        msgType: MeasurementSegmentCreatedMessage,
        func: (e, t, i) => {
          const n = {
            measure_sid: t.data.sid,
            start_position: t.data.startPosition,
            end_position: t.data.endPosition,
            length: t.data.totalLength,
            segments: t.data.segments,
            temporary: t.data.temporary,
            viewmode: t.data.viewmode,
            floor: he(t.data.floorId, i),
            feature_type: t.data.featureType,
            constraint_style: t.data.constraint,
            continuous: t.data.continuous
          }
          e.track("measure_segment_add", n)
        }
      },
      {
        msgType: MeasurementCreatedMessage,
        func: (e, t, i) => {
          const n = {
            measure_sid: t.data.sid,
            length: t.data.totalLength,
            segments: t.data.segments,
            temporary: t.data.temporary,
            viewmode: t.data.viewmode,
            floor: he(t.data.floorId, i),
            feature_type: t.data.featureType,
            measure_type: t.data.type,
            constraint_style: t.data.constraint,
            continuous: t.data.continuous
          }
          e.track("measure_add", n)
        }
      },
      {
        msgType: MeasurementTitleAddedMessage,
        func: (e, t) => {
          const i = { measure_sid: t.sid, measure_text: t.text }
          e.track("measure_add_title", i)
        }
      },
      {
        msgType: MeasurementTitleChangedMessage,
        func: (e, t) => {
          const i = {
            measure_sid: t.sid,
            measure_old_text: t.oldText,
            measure_new_text: t.newText
          }
          e.track("measure_update_title", i)
        }
      },
      {
        msgType: MeasurementDeletedMessage,
        func: (e, t, i) => {
          const n = {
            measure_sid: t.data.sid,
            length: t.data.totalLength,
            segments: t.data.segments,
            temporary: t.data.temporary,
            viewmode: t.data.viewmode,
            floor: he(t.data.floorId, i),
            measure_count: t.data.count,
            continuous: t.data.continuous
          }
          e.track("measure_remove", n)
        }
      },
      {
        msgType: MeasurementUpdatedMessage,
        func: (e, t, i) => {
          const n = {
            measure_sid: t.data.sid,
            length: t.data.totalLength,
            segments: t.data.segments,
            temporary: t.data.temporary,
            viewmode: t.data.viewmode,
            floor: he(t.data.floorId, i),
            feature_type: t.data.featureType,
            constraint_style: t.data.constraint,
            continuous: t.data.continuous
          }
          e.track("measure_update", n)
        }
      },
      {
        msgType: MeasurementModeToggledMessage,
        func: (e, t) => {
          const i = t.opened ? "measure_mode_enter" : "measure_mode_exit",
            n = { viewmode: t.viewmode, measure_count: t.count }
          e.track(i, n)
        }
      },
      {
        msgType: MeasurementCreationCancelledMessage,
        func: (e, t) => {
          e.track("measure_cancelled", {})
        }
      }
    ]
  }
}
import LocaleModule from "./LocaleModule"
import { ActivityPingMessage } from "../message/ping.message"
class ActivityAnalytics {
  handlers: { msgType: typeof ActivityPingMessage; func: (e: any, t: any) => void }[]
  constructor() {
    this.handlers = [
      {
        msgType: ActivityPingMessage,
        func: (e, t) => {
          const i = {
            duration_dollhouse: t.durationDollhouse,
            duration_floorplan: t.durationFloorplan,
            duration_inside: t.durationInside,
            duration: t.durationDollhouse + t.durationFloorplan + t.durationInside,
            main_mode: t.mainMode,
            bytes_downloaded: t.totalBytesDownloaded,
            tiles_downloaded: t.tilesDownloaded
          }
          e.track("activity_ping", i)
        }
      }
    ]
  }
}

import { KeyEvent } from "../event/KeyEvent"
import { PointerButtonEvent } from "../event/PointerEvent"
import { TileDownloadedMessage } from "../message/tile.message"
var pe = {
  UNINITIALIZED: "uninitialized",
  INACTIVE: "inactive",
  ACTIVE: "active"
}

class ShowcaseActivityTracking {
  name: string
  _state: any
  activeModeMap: Map<any, any>
  totalTilesDownloaded: number
  onTileDownloaded: () => void
  engine: any
  requestQueue: any
  input: any
  viewmodeData: any
  applicationData: any
  constructor() {
    ;(this.name = "activity-analytics"),
      (this._state = pe.UNINITIALIZED),
      (this.activeModeMap = new Map()),
      (this.totalTilesDownloaded = 0),
      (this.onTileDownloaded = () => {
        this.totalTilesDownloaded++
      })
  }
  async init(e, t, i) {
    ;(this.engine = e),
      (this.requestQueue = i),
      ([this.input, this.viewmodeData, this.applicationData] = await Promise.all([
        await e.getModuleBySymbol(SymbolList.INPUT),
        await e.market.waitForData(ViewmodeData),
        await e.market.waitForData(ApplicationData)
      ]))
    const n = [],
      s = [ClickEvent, DragEvent, KeyEvent, PointerButtonEvent, PinchEvent],
      r = () => (this.active = !0)
    this.applicationData.phase === phaseMin.PLAYING
      ? (this._state = pe.INACTIVE)
      : n.push(
          e.subscribe(AppPhaseChangeMessage, () => {
            this.applicationData.phase === phaseMin.PLAYING && (this._state = pe.INACTIVE)
          })
        ),
      n.push(
        ...(() => {
          const e = []
          return (
            s.forEach(t => {
              e.push(this.input.registerUnfilteredHandler(t, r))
            }),
            e
          )
        })()
      ),
      n.push(
        e.subscribe(EndSwitchViewmodeMessage, e => {
          const t = e.fromMode,
            i = e.toMode
          t && t !== viewmodeEnum.Transition && this.applicationData.phase === phaseMin.PLAYING && this.handleModeChange(t, i)
        })
      ),
      n.push(this.engine.subscribe(TileDownloadedMessage, this.onTileDownloaded)),
      t(n)
  }
  get active() {
    return this._state === pe.ACTIVE
  }
  set active(e) {
    this._state !== pe.UNINITIALIZED && (e && this._state === pe.INACTIVE && this.startActivityTimeout(), (this._state = e ? pe.ACTIVE : pe.INACTIVE))
  }
  handleModeChange(e, t) {
    this.activeModeMap.has(t)
      ? this.updateActivityTimeForMode(t, !0)
      : this.activeModeMap.set(t, {
          previousTime: Date.now(),
          totalTimeinMS: 0
        }),
      this.updateActivityTimeForMode(e)
  }
  updateActivityTimeForMode(e, t?) {
    const i = this.activeModeMap.get(e)
    if (void 0 === i) return
    const { previousTime: n, totalTimeinMS: s } = i
    t
      ? this.activeModeMap.set(e, {
          previousTime: Date.now(),
          totalTimeinMS: s
        })
      : this.activeModeMap.set(e, {
          previousTime: Date.now(),
          totalTimeinMS: s + (Date.now() - n)
        })
  }
  startActivityTimeout() {
    this.activeModeMap.set(viewmodeEnum.Dollhouse, {
      previousTime: Date.now(),
      totalTimeinMS: 0
    }),
      this.activeModeMap.set(viewmodeEnum.Floorplan, {
        previousTime: Date.now(),
        totalTimeinMS: 0
      }),
      this.activeModeMap.set(viewmodeEnum.Panorama, {
        previousTime: Date.now(),
        totalTimeinMS: 0
      }),
      window.setTimeout(this.notifyActivityAnalytic.bind(this), ShowcaseActivityTracking.ACTIVITY_INTERVAL)
  }
  static ACTIVITY_INTERVAL: any
  notifyActivityAnalytic() {
    if (
      (this.viewmodeData.currentMode &&
        this.viewmodeData.currentMode !== viewmodeEnum.Transition &&
        this.updateActivityTimeForMode(this.viewmodeData.currentMode),
      this.active)
    ) {
      let e = 0,
        t = viewmodeEnum.Panorama
      this.activeModeMap.forEach((i, n) => {
        i.totalTimeinMS > e && ((t = n), (e = i.totalTimeinMS))
      }),
        (this.active = !1)
      const [i, n, s] = [
        this.activeModeMap.get(viewmodeEnum.Dollhouse),
        this.activeModeMap.get(viewmodeEnum.Floorplan),
        this.activeModeMap.get(viewmodeEnum.Panorama)
      ].map(e => (e ? e.totalTimeinMS : 0))
      this.engine.broadcast(new ActivityPingMessage(i, n, s, viewmodeConst[t], this.requestQueue.totalBytesDownloaded, this.totalTilesDownloaded))
    }
  }
}
ShowcaseActivityTracking.ACTIVITY_INTERVAL = 15000
var Ee = {
  USER: "self-guided",
  TOUR: "tour"
}

class RoomDataAnalytics {
  handlers: { msgType: typeof RoomVisitedMessage; func: (e: any, t: any, i: any) => void }[]
  constructor() {
    this.handlers = [
      {
        msgType: RoomVisitedMessage,
        func: (e, t, i) => {
          const n = i.tryGetData(InteractionmodeData),
            s = i.tryGetData(TourData),
            r = {
              room_id: t.roomId,
              room_index: t.meshSubgroup,
              room_type: t.roomType,
              viewmode: t.viewmode ? viewmodeConst[t.viewmode] : t.viewmode,
              room_visit_count: t.visitCount,
              room_count: t.roomCount,
              navigation_source: s && s.tourPlaying ? Ee.TOUR : Ee.USER,
              interaction_source: n ? n.source : InteractionmodeData.defaultSource,
              interaction_mode: n ? n.mode : InteractionmodeData.defaultMode
            }
          e.track("room_visited", r)
        }
      }
    ]
  }
}
import { RTLDisabledRoomnavMessage } from "../message/rtl.message"
class ShowcaseLabelAnalytics {
  handlers: { msgType: typeof RTLDisabledRoomnavMessage; func: (e: any, t: any, i: any) => void }[]
  constructor() {
    this.handlers = [
      {
        msgType: RTLDisabledRoomnavMessage,
        func: (e, t, i) => {
          e.track("internal_warning", {
            warningType: "rtl_disabled_roomnav"
          })
        }
      }
    ]
  }
}
import { phaseMin } from "../enum/phase.enum"
import sweepAlignmentEnum from "../enum/sweepAlignment.enum"
import sweepPlacementEnum from "../enum/sweepPlacement.enum"
import viewmodeConst from "../constant/viewmode.const"
import { BeginMoveToSweepMessage, EndMoveToSweepMessage, SweepFloorOverrideMessage } from "../message/sweeps.messge"
import { ClickEvent, PinchEvent } from "../event/GestureEvent"
import { DragEvent } from "../event/DragEvent"
import keyConst from "../constant/key.const"
import { ModelRatedMessage } from "../message/model.message"
import { PixelRatioChangedMessage } from "../message/ratio.message"
import analyticsEnum from "../enum/analytics.enum"
import { EndMoveToFloorMessage } from "../message/floor.message"
import { RoomVisitedMessage } from "../message/room.message"
import viewmodeEnum from "../enum/viewmode.enum"
import WebGLRendererModule from "./WebGLRendererModule"
const xe = e => e.sort((e, t) => e.localeCompare(t))
class ModelRatingAnalytics {
  handlers: { msgType: typeof ModelRatedMessage; func: (e: any, t: any) => void }[]
  constructor() {
    this.handlers = [
      {
        msgType: ModelRatedMessage,
        func: (e, t) => {
          const { happiness: i, quality: n, navigation: s, feedback: r } = t.rating,
            o: any = {}
          i && (o.happiness = +i),
            ((s && s.length > 0) || (n && n.length > 0)) &&
              (o.issue_types = (function (e = [], t = []) {
                const i = []
                return xe(t).forEach(e => i.push(`navigation-${e.trim()}`)), xe(e).forEach(e => i.push(`quality-${e.trim()}`)), i.join(",")
              })(n || [], s || [])),
            r && r.length > 0 && (o.feedback = r),
            Object.keys(o).length > 0 && e.track("model_rated", o)
        }
      }
    ]
  }
}
const Ae = new Logger("showcase-analytics")
export default class ShowcaseAnalytics extends Module {
  loaded: boolean
  handlers: any[]
  track: (e: any, t: any) => void
  analytics: any
  apiClient: any
  context: { app: { name: string; version: string }; locale: any; screen: { width: number; height: number; density: number }; timezone: string; location: {} }
  options: any
  activityTracking: ShowcaseActivityTracking
  constructor() {
    super(...arguments),
      (this.name = "showcase-analytics"),
      (this.loaded = !1),
      (this.handlers = []),
      (this.track = (e, t) => {
        this.analytics.track(e, t)
      })
  }
  async init(e, t) {
    this.analytics = await t.getModule(AnalyticsModule)
    this.apiClient = (await t.getModule(ApiClientModule)).getApi()
    const i = await t.market.waitForData(SettingsData)
    const n = await t.getModule(LocaleModule)
    this.addMessageHandlers(this.analytics, t),
      (this.context = (function (e, t, i) {
        const n = v(t, i)
        return (
          funcUtil.localType().then(e => {
            n.location = {
              city: e.city,
              country: e.country,
              region: e.region
            }
          }),
          n
        )
      })(e.apiQueue, n.languageCode, e.appName)),
      (this.options = Object.assign(
        Object.assign(
          { mds_enabled: i.tryGetProperty(keyConst.settings.storage.mds, !1) },
          {
            model_id: paramsUtil.getModelID(),
            start_source: funcUtil.getUrlParams("play", !1) ? "autoplay" : browserUtil.diffWindow() ? "click" : "fullpage",
            autoplay: funcUtil.getUrlParams("play", !1) || !browserUtil.diffWindow(),
            quickstart: 1 === funcUtil.getUrlParams("qust", 0) || 1 === funcUtil.getUrlParams("qs", 0),
            language_tag: funcUtil.getUrlParams("lang", null),
            is_mobile: browserUtil.isMobile(),
            iframe: browserUtil.diffWindow(),
            aspect_ratio: browserUtil.aspectRatio(),
            session_id: p.D(),
            window: {
              height: window.innerHeight,
              width: window.innerWidth
            },
            platform: f()
          }
        ),
        e.additionalValues
      )),
      (this.activityTracking = new ShowcaseActivityTracking()),
      this.activityTracking.init(t, this.registerBindings.bind(this), e.apiQueue)
    const o = await this.createAnalyticsConfigs(e, i)
    this.analytics.load(o, e.analyticsQueue, this.options, this.context, this.apiClient.user).then(() => {
      this.loaded = !0
    })
  }
  addMessageHandlers(e, t) {
    this.addMessageHandler(new ShowcaseSessionAnalytics(e, t), t),
      this.addMessageHandler(new ViewmodeAnalytics(), t),
      this.addMessageHandler(new CameraDataAnalytics(), t),
      this.addMessageHandler(new InteractionmodeAnalytics(), t),
      this.addMessageHandler(new FloorChangeAnalytics(), t),
      this.addMessageHandler(new MattertagDataAnalytics(), t),
      this.addMessageHandler(new ZoomAnalytics(), t),
      this.addMessageHandler(new MeasurementAnalytics(), t),
      this.addMessageHandler(new RenderingPerformanceAnalytics(), t),
      this.addMessageHandler(new ActivityAnalytics(), t),
      this.addMessageHandler(new RoomDataAnalytics(), t),
      this.addMessageHandler(new ShowcaseLabelAnalytics(), t),
      this.addMessageHandler(new ModelRatingAnalytics(), t)
  }
  addMessageHandler(e, t) {
    this.handlers.push(e),
      e.handlers.forEach((e, i) => {
        this.bindings.push(
          t.subscribe(e.msgType, i => {
            e.func(this.analytics, i, t.market)
          })
        )
      })
  }
  registerBindings(e) {
    this.bindings.push(...e)
  }
  async createAnalyticsConfig(e, t) {
    if (
      ((e, t) => {
        const i = Object.keys(e)
        for (const n of i) if (e[n] === t) return !0
        return !1
      })(analyticsEnum, e)
    ) {
      const { apiClient: i } = this,
        n = AnalyticsConfig[e],
        s = null !== n.key ? await i.getAppKey(t, n.key) : null,
        r = null !== n.url ? await i.getAppKey(t, n.url) : null
      if (null === n.key || (null !== s && null === n.url) || null !== r) return { provider: e, token: s, url: r }
    }
    return null
  }
  async createAnalyticsConfigs(e, t) {
    const i = e.appName,
      n = void 0 !== e.provider ? e.provider : await this.apiClient.getAppKey(i, "analytics_provider"),
      s = []
    if (!n) return s
    const r = n.split(",")
    for (const e of r) {
      const t = await this.createAnalyticsConfig(e, i)
      null !== t ? s.push(t) : Ae.warn(`Failed to set up ${e}, token/url required but not found in config`)
    }
    return s.length < 1 && s.push({ provider: y, token: null, url: null }), s
  }
  onUpdate(e) {
    this.loaded &&
      ((e, t) => {
        X && (ie.push(t), ($ += t), $ >= Q && (re(e), se()))
      })(this.analytics, e)
  }
  dispose(e) {
    super.dispose(e)
    for (const e of this.handlers) e.dispose && e.dispose()
    this.handlers = []
  }
  getSessionId() {
    return this.options.session_id
  }
}
